package com.easy.aspect;

import com.easy.annotation.LogMethod;
import com.easy.bean.Log;
import com.easy.mapper.LogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Aspect
@Component
public class LogAspect {

    @Autowired
    private LogMapper logMapper;

    @Pointcut(value = "@annotation(com.easy.annotation.LogMethod)")
    public void logmethod(){}

    @Around(value = "@annotation(logMethod)")
    public Object recordLog(ProceedingJoinPoint point, LogMethod logMethod) throws Throwable {
        Object obj = null;
        long startTime = System.currentTimeMillis();

        // 获取方法信息
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        String methodName = methodSignature.getMethod().getName();
        String serviceName = logMethod.serviceName();
        boolean recordParam = logMethod.recordParam();
        boolean recordReturn = logMethod.recordReturn();

        // 记录参数
        String params = null;
        if (recordParam) {
            Object[] args = point.getArgs();
            StringBuilder paramBuilder = new StringBuilder();
            for (int i = 0; i < args.length; i++) {
                if (i > 0) paramBuilder.append(", ");
                paramBuilder.append(args[i]);
            }
            params = paramBuilder.toString();
        }

        try {
            // 执行目标方法
            obj = point.proceed();
            return obj;
        } finally {
            // 计算执行时间
            long endTime = System.currentTimeMillis();
            String executionTime = (endTime - startTime) + "ms";

            // 记录返回值
            String returnValue = null;
            if (recordReturn && obj != null) {
                returnValue = obj.toString();
            }

            // 创建日志对象
            Log log = new Log();
            log.setServiceName(serviceName);
            log.setMethodName(methodName);
            log.setParams(params);
            log.setReturnValue(returnValue);
            log.setCreateTime(new Date());
            log.setExecutionTime(executionTime);

            // 保存到数据库（异步保存避免影响主流程）
            saveLogAsync(log);
        }
    }

    // 异步保存日志
    private void saveLogAsync(Log log) {
        new Thread(() -> {
            try {
                logMapper.insertLog(log);
            } catch (Exception e) {
                System.err.println("保存日志失败: " + e.getMessage());
                e.printStackTrace();
            }
        }).start();
    }
}
